import express from 'express'
import cors from 'cors'
import jwt from 'jsonwebtoken'
import bcrypt from 'bcryptjs'
import pool from './db/mysql'
import { body, validationResult } from 'express-validator'
import { ResultSetHeader, RowDataPacket, OkPacket } from 'mysql2'

const app = express()
const JWT_SECRET = process.env.JWT_SECRET || 'your-secret-key'

interface CustomRequest extends express.Request {
    user?: {
        id: number;
        username: string;
    };
}

interface User extends RowDataPacket {
    id: number;
    username: string;
    email: string;
    password: string;
}

interface Device extends RowDataPacket {
    id: number;
    user_id: number;
    name: string;
    type: string;
    location: string;
    status: boolean;
}

// 中间件
app.use(cors())
app.use(express.json())

// 认证中间件
const authenticateToken = (req: CustomRequest, res: express.Response, next: express.NextFunction) => {
    const authHeader = req.headers['authorization']
    const token = authHeader && authHeader.split(' ')[1]

    if (!token) {
        return res.status(401).json({ error: '未提供认证令牌' })
    }

    jwt.verify(token, JWT_SECRET, (err: any, user: any) => {
        if (err) {
            return res.status(403).json({ error: '令牌无效或已过期' })
        }
        req.user = user
        next()
    })
}

// 注册路由
app.post(
    '/api/auth/register',
    [
        body('username').trim().isLength({ min: 3 }),
        body('email').isEmail(),
        body('password').isLength({ min: 6 })
    ],
    async (req, res) => {
        const errors = validationResult(req)
        if (!errors.isEmpty()) {
            return res.status(400).json({ errors: errors.array() })
        }

        const { username, email, password } = req.body

        try {
            const hashedPassword = await bcrypt.hash(password, 10)

            const [result] = await pool.query(
                'INSERT INTO users (username, email, password) VALUES (?, ?, ?)',
                [username, email, hashedPassword]
            )

            res.status(201).json({
                message: '注册成功',
                userId: result.insertId
            })
        } catch (error) {
            res.status(500).json({ error: '注册失败' })
        }
    }
)

// 登录路由
app.post('/api/auth/login', async (req, res) => {
    const { username, password } = req.body

    try {
        const [user] = await pool.query(
            'SELECT * FROM users WHERE username = ?',
            [username]
        )

        if (user.length === 0) {
            return res.status(401).json({ error: '用户名或密码错误' })
        }

        const validPassword = await bcrypt.compare(password, user[0].password)
        if (!validPassword) {
            return res.status(401).json({ error: '用户名或密码错误' })
        }

        const token = jwt.sign(
            { id: user[0].id, username: user[0].username },
            JWT_SECRET,
            { expiresIn: '24h' }
        )

        res.json({
            token,
            user: {
                id: user[0].id,
                username: user[0].username,
                email: user[0].email
            }
        })
    } catch (error) {
        res.status(500).json({ error: '登录失败' })
    }
})

// 设备路由
app.get('/api/devices', authenticateToken, async (req: CustomRequest, res: express.Response) => {
    try {
        const [rows] = await pool.query<Device[]>(
            'SELECT * FROM devices WHERE user_id = ? ORDER BY created_at DESC',
            [req.user?.id]
        )
        res.json(rows)
    } catch (error) {
        console.error('获取设备列表失败:', error)
        res.status(500).json({ error: '获取设备列表失败' })
    }
})

app.post('/api/devices', authenticateToken, async (req: CustomRequest, res: express.Response) => {
    const { name, type, location } = req.body
    const userId = req.user?.id

    try {
        const [result] = await pool.query<ResultSetHeader>(
            'INSERT INTO devices (user_id, name, type, location) VALUES (?, ?, ?, ?)',
            [userId, name, type, location]
        )

        res.status(201).json({
            id: result.insertId,
            name,
            type,
            location,
            status: false,
            user_id: userId
        })
    } catch (error) {
        console.error('添加设备失败:', error)
        res.status(500).json({ error: '添加设备失败' })
    }
})

app.delete('/api/devices/:id', authenticateToken, async (req: CustomRequest, res: express.Response) => {
    const deviceId = req.params.id
    const userId = req.user?.id

    try {
        const [result] = await pool.query<ResultSetHeader>(
            'DELETE FROM devices WHERE id = ? AND user_id = ?',
            [deviceId, userId]
        )

        if (result.affectedRows === 0) {
            return res.status(404).json({ error: '设备不存在或无权限' })
        }

        res.json({ message: '设备已删除' })
    } catch (error) {
        console.error('删除设备失败:', error)
        res.status(500).json({ error: '删除设备失败' })
    }
})

// 更新设备状态
app.put('/api/devices/:id/status', authenticateToken, async (req: CustomRequest, res: express.Response) => {
    const deviceId = req.params.id
    const userId = req.user?.id
    const { status } = req.body

    try {
        const [result] = await pool.query<ResultSetHeader>(
            'UPDATE devices SET status = ? WHERE id = ? AND user_id = ?',
            [status, deviceId, userId]
        )

        if (result.affectedRows === 0) {
            return res.status(404).json({ error: '设备不存在或无权限' })
        }

        const [[device]] = await pool.query<Device[]>(
            'SELECT * FROM devices WHERE id = ?',
            [deviceId]
        )

        res.json(device)
    } catch (error) {
        console.error('更新设备状态失败:', error)
        res.status(500).json({ error: '更新设备状态失败' })
    }
})

const PORT = process.env.PORT || 3000
app.listen(PORT, () => {
    console.log(`服务器运行在 http://localhost:${PORT}`)
}) 